#ifndef APPLICATION_H_
#define APPLICATION_H_

class TransformObject;
class TextureMaterial;
class ShaderMaterial;
class VboGrid;
class SkyBox;

namespace nv{
	template <class T> class vec3;
}

#include <string>

class Application{

public:

	static Application *getInstance();
	static void destroy();

	static float getFps(){

		return getInstance()->fps;

	}
	void init(int argc, char **argv);

private:

	Application();
	~Application();

	static Application * app;

	int timebase, frame, totalFrame;
	float fps;
	bool showDebugText, fullScreen;
	int mouse_x, mouse_y, mouse_btnState, view_width, view_height;

	float camera_speed_mod, camera_rotation_mod;
	TransformObject *camera;
	nv::vec3<float> *camera_speed;
	float camAngle;

	TextureMaterial *recordingTex;
	float recordFps;
	int recordSteps, recordedFrames;
	bool recording;
	std::string recordLocation;

	VboGrid *terrain;
	ShaderMaterial *terrainShader;

	SkyBox *skyBox;

	void render();
	void renderDebugText();
	void setFullScreen();


	void keyDown(int key, int , int );
	void keyUp(int key, int , int );
	void mouseAction(int button, int state, int x, int y);
	void mouseMove(int x, int y);
	void idle();
	void reshape(int w, int h);

	// evidently they must be static.
	static void g_keyboardSpecial(int key, int x, int y){app->keyDown(key, x, y);}
	static void g_keyboardSpecialUp(int key, int x, int y){app->keyUp(key, x, y);}
	static void g_keyboard(unsigned char key, int x, int y){app->keyDown((int)key, x, y);}
	static void g_keyboardUp(unsigned char key, int x, int y){app->keyUp((int)key, x, y);}
	static void g_render(){app->render();}
	static void g_idle(){app->idle();}
	static void g_mouseAction(int button, int state, int x, int y){app->mouseAction(button, state, x, y);}
	static void g_mouseMove(int x, int y){app->mouseMove(x,y);}
	static void g_reshape(int w, int h){ app->reshape(w, h);}

};

#endif /* APPLICATION_H_ */
